/* course-application.c
 *
 * Copyright 2023 korack
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include "CourseApplication.h"

#include "CourseObject.h"
#include "CourseWindow.h"
#include "config.h"

struct _CourseApplication
{
        AdwApplication parent_instance;
        CourseObject*  course;
        int            argc;
        char**         argv;
};

G_DEFINE_TYPE (CourseApplication, course_application, ADW_TYPE_APPLICATION)

CourseApplication*
course_application_new (const char* application_id, GApplicationFlags flags)
{
        g_return_val_if_fail (application_id != NULL, NULL);

        return g_object_new (COURSE_TYPE_APPLICATION,
                             "application-id",
                             application_id,
                             "flags",
                             flags,
                             NULL);
}

const char*
course_get_default_file ()
{
        char*       home_path;
        static char file_name[45] = {0};

        /*获取 $HOME */
        home_path = getenv ("HOME");
        if (home_path) {
                strcpy (file_name, home_path);
        } else {
                OBJECT_WARNING_TOOL (CourseApplication,
                                     get_default_file,
                                     "未获取到环境变量 $HOME！\n");
        }

        strcat (file_name, "/example.sch");

        OBJECT_INFO_TOOL (CourseApplication,
                          get_default_file,
                          "获取到默认文件路径 '%s'\n",
                          file_name);

        return file_name;
}

static void
course_application_load_sch_file (CourseApplication* app)
{
        int state;
        g_assert (COURSE_IS_APPLICATION (app));

        if (app->argc == 1) {
                state = course_object_load_sch (app->course, COURSE_FILE);
        } else if (app->argc == 2) {
                state = course_object_load_sch (app->course, app->argv[1]);
        } else {
                OBJECT_ERROR_TOOL (CourseApplication,
                                   load_sch_file,
                                   "参数多于了一个，参数只能为文件名。\n");
                state = 1;
        }

        if (!state)
                state = course_object_analysis_sch (app->course);
        if (state) {
                OBJECT_ERROR_TOOL (CourseApplication,
                                   load_sch_file,
                                   "打开课程表文件后出现错误！\n");
        } else {
                course_object_add_all_course_in_current_week (app->course);
        }
}

static void
course_application_activate (GApplication* app)
{
        GtkWindow*         window;
        CourseApplication* capp;

        g_assert (COURSE_IS_APPLICATION (app));

        capp   = COURSE_APPLICATION (app);

        window = gtk_application_get_active_window (GTK_APPLICATION (app));

        if (window == NULL) {
                window = g_object_new (COURSE_TYPE_WINDOW,
                                       "application",
                                       app,
                                       NULL);
        }

        course_application_load_sch_file (capp);
        course_window_set_course (COURSE_WINDOW (window), capp->course);
        course_window_render_once (COURSE_WINDOW (window));
        gtk_window_present (window);
}

static void
course_application_finalize (GObject* object)
{
        CourseApplication* app = COURSE_APPLICATION (object);
        G_OBJECT_CLASS (course_application_parent_class)->finalize (object);
        object_unref (app->course);
}

static void
course_application_class_init (CourseApplicationClass* klass)
{
        GObjectClass*      object_class = G_OBJECT_CLASS (klass);
        GApplicationClass* app_class    = G_APPLICATION_CLASS (klass);

        object_class->finalize          = course_application_finalize;
        app_class->activate             = course_application_activate;
}

void
course_application_set_args (CourseApplication* app, int argc, char** argv)
{
        g_assert (COURSE_IS_APPLICATION (app));
        app->argc = argc;
        app->argv = argv;
}

static void
course_application_about_action (GSimpleAction* action,
                                 GVariant*      parameter,
                                 gpointer       user_data)
{
        static const char* developers[] = {"korack/咸鱼雨涵", NULL};
        CourseApplication* self         = user_data;
        GtkWindow*         window       = NULL;

        g_assert (COURSE_IS_APPLICATION (self));

        window = gtk_application_get_active_window (GTK_APPLICATION (self));

        adw_show_about_window (window,
                               "application-name",
                               GETTEXT_PACKAGE,
                               "application-icon",
                               "kcourse",
                               "developer-name",
                               "korack/咸鱼雨涵",
                               "version",
                               PACKAGE_VERSION,
                               "developers",
                               developers,
                               "copyright",
                               "© 2023 korack/咸鱼雨涵",
                               NULL);
}

static void
course_application_quit_action (GSimpleAction* action,
                                GVariant*      parameter,
                                gpointer       user_data)
{
        CourseApplication* self = user_data;

        g_assert (COURSE_IS_APPLICATION (self));

        g_application_quit (G_APPLICATION (self));
}

static const GActionEntry app_actions[] = {
        { "quit",  course_application_quit_action},
        {"about", course_application_about_action},
};

static void
course_application_init (CourseApplication* self)
{
        g_action_map_add_action_entries (G_ACTION_MAP (self),
                                         app_actions,
                                         G_N_ELEMENTS (app_actions),
                                         self);
        gtk_application_set_accels_for_action (
                GTK_APPLICATION (self),
                "app.quit",
                (const char*[]) {"<primary>q", NULL});

        self->course = course_object_new ();
}
